﻿using HW_CommunicationLib.Model;
using HW_PlcLib;
using HW_PlcLib.Model;
using HW_PlcLib.Mvvm;
using Plc_Communication_Demo.Model;
using Prism.Commands;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Plc_Communication_Demo.ViewModels
{
        public class MainViewModel : ObservableObject
        {

        private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        public KeyencePlc KeyencePlc { get; set; } = new KeyencePlc();

        private string _inputAddressText;

        private string _inputPortText;

        private string _inputCommandText;

        private string _inputDataText;

        public ICommand TestProcessCommand { get; }

        public ICommand CloseTestProcessCommand { get; }

        public string InputAddressText
        {
            get { return _inputAddressText; }
            set { _inputAddressText = value; RaisePropertyChanged(); }
        }
        public string InputPortText
        {
            get { return _inputPortText; }
            set { _inputPortText = value; RaisePropertyChanged(); }
        }
        public string InputCommandText
        {
            get { return _inputCommandText; }
            set
            {
                _inputCommandText = value;RaisePropertyChanged();
            }
        }

        public string InputDataText
        {
            get { return _inputDataText; }
            set
            {
                _inputDataText = value; RaisePropertyChanged();
            }
        }



        private ObservableCollection<Message> messageList = new ObservableCollection<Message>();
            public ObservableCollection<Message> MessageList
            {
                get { return messageList; }
                set { messageList = value; RaisePropertyChanged(); }
            }

            private ObservableCollection<Message> byteList = new ObservableCollection<Message>();
            public ObservableCollection<Message> ByteList
            {
                get { return byteList; }
                set { byteList = value; RaisePropertyChanged(); }
            }

            public MainViewModel()
            {
            TestProcessCommand = new DelegateCommand(StartTestProcess);
            CloseTestProcessCommand = new DelegateCommand(StopTestProcess);
            KeyencePlc.OnError += KeyencePlc_OnMessage;
            KeyencePlc.OnMessage += KeyencePlc_OnMessage;
            KeyencePlc.OnSend += KeyencePlc_OnSend;
            KeyencePlc.OnReceived += KeyencePlc_OnReceived;
            }



        private void KeyencePlc_OnReceived(object arg1, HW_CommunicationLib.Model.DataPackage package)
        {
            Message message = new Message();
            message.DateTime = package.ReceiveTime;
            message.Content = "接收:" + package.Result.ToString();
            System.Windows.Application.Current.Dispatcher.Invoke(() => ByteList.Insert(0, message));
        }

        private void KeyencePlc_OnSend(object arg1, HW_CommunicationLib.Model.DataPackage package)
        {
            Message message = new Message();
            message.DateTime = package.SendTime;
            message.Content = "下发:" + package.SendBufferToString;
            System.Windows.Application.Current.Dispatcher.Invoke(() => ByteList.Insert(0, message));
        }

        private void KeyencePlc_OnMessage(object sender, HW_PlcLib.Model.PlcEventArgs arg)
        {
            Message message = new Message();
            message.DateTime = DateTime.Now;
            message.Content = arg.Message;
            System.Windows.Application.Current.Dispatcher.Invoke(() => MessageList.Insert(0, message));
        }


        private void StartTestProcess()
        {
            cancellationTokenSource = new CancellationTokenSource();
            Task.Run(() =>
            {
                
                while (!cancellationTokenSource.Token.IsCancellationRequested)
                {
                    try
                    {
                        //面1量
                        KeyencePlc.Write_Float("EM6080", GenerateRandomDecimalToString());
                        //面1角度
                        KeyencePlc.Write_Float("EM3060", GenerateRandomDecimalToString());
                        //面1单位
                        KeyencePlc.Write_String("EM5162", GenerateUnit());
                        //面2量
                        KeyencePlc.Write_Float("EM6082", GenerateRandomDecimalToString());
                        //面2角度
                        KeyencePlc.Write_Float("EM3064", GenerateRandomDecimalToString());
                        //面2单位
                        KeyencePlc.Write_String("EM5178", GenerateUnit());

                        //面3量
                        KeyencePlc.Write_Float("EM6084", GenerateRandomDecimalToString());
                        //面3角度
                        KeyencePlc.Write_Float("EM3068", GenerateRandomDecimalToString());
                        //面3单位
                        KeyencePlc.Write_String("EM5182", GenerateUnit());

                        //面4量
                        KeyencePlc.Write_Float("EM6086", GenerateRandomDecimalToString());
                        //面4角度
                        KeyencePlc.Write_Float("EM3072", GenerateRandomDecimalToString());
                        //面4单位
                        KeyencePlc.Write_String("EM5166", GenerateUnit());

                        //公差
                        KeyencePlc.Write_Float("EM290", GenerateRandomDecimalToString());

                        KeyencePlc.Write_Float("EM292", GenerateRandomDecimalToString());

                        KeyencePlc.Write_Float("EM294", GenerateRandomDecimalToString());

                        KeyencePlc.Write_Float("EM296", GenerateRandomDecimalToString());

                        Console.WriteLine(KeyencePlc.Read_Float("EM290") +
                                            KeyencePlc.Read_Float("EM292") +
                                            KeyencePlc.Read_Float("EM294") +
                                            KeyencePlc.Read_Float("EM296"));
;
                        //工件型号
                        KeyencePlc.Write_String("EM142", GenerateNumberOfJobs());
                        //产品编号
                        KeyencePlc.Write_String("EM16340", GenerateProductNumber());
                        //合格
                        KeyencePlc.SET_Addr("MR40406");

                        Thread.Sleep(5000);
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            });
        }

        private void StopTestProcess()
        {
            cancellationTokenSource.Cancel();
        }


            static string GenerateProductNumber()
        {
            return Guid.NewGuid().ToString().Substring(0, 8);
        }

        static string GenerateNumberOfJobs()
        {
            return "NO" + new Random().Next(1, 100).ToString();
        }

        static string GenerateUnit()
        {
            string[] units = { "g","gcm" };
            Random random = new Random();
            string unit = units[random.Next(units.Length)];
            return unit;
        }

            static string GenerateRandomDecimalToString()
        {
            Random random = new Random();
            decimal value = Math.Round((decimal)(random.NextDouble() * 100), 2);
            string result = value.ToString();
            return result;
        }
    }
}
